import json
import re
from typing import Dict, Optional, Tuple


class GoCodeExtractor:
    def __init__(self):
        # 编译正则表达式用于匹配标记
        self.meta_pattern = re.compile(r'//\s*@META\.(struct|table):(tqt|svr|json)')
        # 匹配结构体定义
        self.struct_pattern = re.compile(r'type\s+(\w+)\s+struct\s*{')
        # 匹配多行注释
        self.comment_pattern = re.compile(r'/\*(.*?)\*/', re.DOTALL)

    @classmethod
    def extract_from_file(cls, file_path: str) -> Dict[str, str]:
        """从Go源文件中提取标记的结构体和多行注释"""
        with open(file_path, 'r', encoding='utf-8') as f:
            content = f.read()

        return cls.extract_from_content(content)

    @classmethod
    def extract_from_content(cls, content: str) -> Dict[str, str]:
        """
        从Go源代码内容中提取标记的结构体和多行注释
        返回结构:
        {
            "TqtAward": "type TqtAward struct {}",
            "table": [
                [],
                []
            ]
            "SvrAward": "type SvrAward struct {}"
        }
        """
        extractor = cls()
        result = {}
        lines = content.split('\n')
        i = 0
        while i < len(lines):
            line = lines[i].strip()
            meta_match = extractor.meta_pattern.search(line)
            if meta_match:
                meta_type, meta_value = meta_match.groups()
                if meta_type == 'struct':
                    # 处理结构体提取
                    struct_name, struct_def = extractor._extract_struct(lines, i + 1)
                    if struct_name and struct_def:
                        key = f"{struct_name}"  # 例如 "TqtAward"
                        result[key] = struct_def
                        # 跳过已处理的行
                        i += struct_def.count('\n') + 1
                elif meta_type == 'table':
                    # 处理多行注释提取
                    comment = extractor._extract_multiline_comment(lines, i + 1)
                    if comment:
                        key = "table"
                        # 去除注释标记并清理内容
                        clean_comment = extractor._clean_comment(comment)
                        result[key] = json.loads(clean_comment)
                        # 跳过已处理的行
                        i += comment.count('\n') + 1
            i += 1
        return result

    def _clean_comment(self, comment: str) -> str:
        """去除多行注释的标记并清理内容"""
        # 使用正则表达式提取注释内容（去除/*和*/）
        match = self.comment_pattern.search(comment)
        if match:
            content = match.group(1)
            # 清理每行的前导*和空格
            cleaned_lines = []
            for line in content.split('\n'):
                # 去除行首的*和空格
                line = line.strip()
                if line.startswith('*'):
                    line = line[1:].strip()
                cleaned_lines.append(line)
            return '\n'.join(cleaned_lines).strip()
        return comment

    def _extract_struct(self, lines: list, start_idx: int) -> Tuple[Optional[str], Optional[str]]:
        """从指定行开始提取结构体定义"""
        for i in range(start_idx, len(lines)):
            struct_match = self.struct_pattern.search(lines[i])
            if struct_match:
                struct_name = struct_match.group(1)
                struct_lines = []
                brace_count = 0
                found_start = False
                # 收集结构体所有行
                for j in range(i, len(lines)):
                    line = lines[j]
                    struct_lines.append(line)
                    # 计算大括号数量
                    brace_count += line.count('{') - line.count('}')
                    # 当遇到第一个{时标记开始
                    if '{' in line and not found_start:
                        found_start = True
                    # 当所有大括号都闭合时结束
                    if found_start and brace_count == 0:
                        struct_def = '\n'.join(struct_lines)
                        return struct_name, struct_def
                # 如果到这里还没返回，说明结构体不完整
                return struct_name, '\n'.join(struct_lines)
        return None, None

    def _extract_multiline_comment(self, lines: list, start_idx: int) -> Optional[str]:
        """从指定行开始提取多行注释"""
        for i in range(start_idx, len(lines)):
            line = lines[i].strip()
            if line.startswith('/*'):
                comment_lines = [line]
                # 检查当前行是否已经结束
                if '*/' in line:
                    return line
                # 继续收集直到找到结束标记
                for j in range(i + 1, len(lines)):
                    next_line = lines[j]
                    comment_lines.append(next_line)
                    if '*/' in next_line:
                        return '\n'.join(comment_lines)
                # 如果没有找到结束标记，返回已收集的内容
                return '\n'.join(comment_lines)
        return None
